package org.ainlolcat.ainscience.column.custom;

import org.ainlolcat.Variable;
import org.ainlolcat.aincalc2.AinCalc;
import org.ainlolcat.aincalc2.Cleks;
import org.ainlolcat.aincalc2.MissingDependenciesException;
import org.ainlolcat.ainscience.Controller;
import org.ainlolcat.ainscience.UpdateListener;
import org.ainlolcat.ainscience.column.Column;
import org.ainlolcat.ainscience.column.CustomColumn;
import org.ainlolcat.ainscience.entity.Entity;
import org.ainlolcat.ainscience.matrix.MatrixFileParser;
import org.ainlolcat.ainscience.statistics.StatisticsCollectorImpl;
import org.apache.log4j.Logger;

import java.util.Collections;
import java.util.Hashtable;
import java.util.Map;

/**
 * @author ainlolcat
 */
public class LinkedTableStatisticsCustomColumn extends CustomColumn implements UpdateListener {
    private static Logger log = Logger.getLogger(LinkedTableStatisticsCustomColumn.class);

    Hashtable<String, String> params;
    Entity entity;
    String linkedEntityName;
    String statistic;

    @Override
    public Column generateColumn(Hashtable<String, String> params, Entity entity) {
        this.params = params;
        this.entity = entity;
        setType(MatrixFileParser.MATRIX_DELIMETER_TYPE_DOUBLE);
        linkedEntityName = params.get("entity");
        statistic = params.get("statistic");
        generateValues();
        Controller.getInstance().addUpdateListener(this);
        return this;
    }

    private void generateValues(){
        try {
            generateValuesInternal();
            Controller.getInstance().throwUpdateEvent(entity, UPDATE_ENTITY_COLUMN);
        } catch (MissingDependenciesException e) {
            throw e;
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private void generateValuesInternal() throws IllegalAccessException, InstantiationException, ClassNotFoundException {
        Entity linkedEntity = Controller.getInstance().getProject().getEntityByName(linkedEntityName);
        if (linkedEntity == null)
            throw new MissingDependenciesException(linkedEntityName);

        Map<String, String> stat = new StatisticsCollectorImpl(linkedEntity).collect();
        double statValue = Double.parseDouble(stat.get(statistic));
        for (int i=0;i<entity.getRowCount();i++){
            values.add(statValue);
        }
    }

    public void onProjectUpdate() {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public void onEntityUpdate(Entity entity, int action) {
        log.debug("Update event income for entity " + entity.getName() + " linked one " + linkedEntityName);
        if (entity.getName().equals(linkedEntityName))
            generateValues();
        if (entity == this.entity)
            try {
                generateValuesInternal();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
    }
}
